/**
 *******************************************************************************
 * @FileName  : tlsr825x_dma.c
 * @Author    : GaoQiu
 * @CreateDate: 2020-09-10
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */
#include "tlsr825x_dma.h"
#include "utils/assert.h"

/*! DMAx register type. */
typedef struct{
	__IO uint16_t ADDR;
	__IO uint8_t  SIZE;
	__IO uint8_t  MODE;
}DMA_Reg_Type_t;


/**
 * @brief : DMA define initialization.
 * @param : None.
 * @return: None.
 */
void DMA_DefInit(void)
{
	DMA->CHN_EN = 0;
	DMA->IRQ_EN = 0;
	//DMA->TX_EN = 0x0011;
}

/**
 * @brief : DMA Channel x configuration.
 * @param : DMA_Channel     DMA channel, can be DMA_Channel_0/DMA_Channel_1...
 * @param : pBuf            Pointer point to memory.
 * @param : byteLen         the length of pBuf.
 * @return: None.
 */
void DMA_Init(uint8_t DMA_Channel, uint8_t *pBuf, uint32_t byteLen)
{
	ASSERT(IS_DMA_CHANNEL(DMA_Channel), DRIV_ERR|DMA_ERR_CHANNEL);

	DMA_Reg_Type_t *DMAx = (DMA_Reg_Type_t *)((uint32_t *)&DMA->CHN0_ADDR + DMA_Channel);
	DMAx->ADDR = (uint16_t)(uint32_t)pBuf;
	DMAx->SIZE = (byteLen>>4);

	if(DMA_Channel == DMA_Channel_7)
	{
		DMAx->MODE &= ~DMA_MODE_WRITE_MEM;//Tx
		return;
	}

	if(((uint32_t)DMAx & 0x0F) == 0x00 || ((uint32_t)DMAx & 0x0F) == 0x08)
	{
		DMAx->MODE |= DMA_MODE_WRITE_MEM; //Rx
	}
	else{
		DMAx->MODE &= ~DMA_MODE_WRITE_MEM;//Tx
	}
}

/**
 * @brief : DMA Channel x Interrupt configuration.
 * @param : DMA_IT          DMA Interrupt, can be DMA_IT_Channel_0/DMA_IT_Channel_1...
 * @param : enable          enable/disable DMA IT
 * @return: None.
 */
void DMA_ITConfig(uint8_t DMA_IT, bool_t enable)
{
	if(enable){
		DMA->IRQ_EN |= DMA_IT;
	}
	else{
		DMA->IRQ_EN &= ~DMA_IT;
	}
}

/**
 * @brief : DMA Channel x enable/disable.
 * @param : DMA_Channel          DMA enable, can be DMA_Channel_0/DMA_Channel_1...
 * @param : enable               enable / disable DMA channel.
 * @return: None.
 */
void DMA_Cmd(uint8_t DMA_Channel, bool_t enable)
{
	ASSERT(IS_DMA_CHANNEL(DMA_Channel), DRIV_ERR|DMA_ERR_CHANNEL);

	if(enable)
	{
		if(DMA_Channel == DMA_Channel_7){
			DMA->CHN_EN |= DMA_CHN_PWM_EN;
			return;
		}

		DMA->CHN_EN |= (1<<DMA_Channel);
	}
	else{
		if(DMA_Channel == DMA_Channel_7){
			DMA->CHN_EN &= ~DMA_CHN_PWM_EN;
			return;
		}

		DMA->CHN_EN &= ~(1<<DMA_Channel);
	}
}

